// Copyright 2007-2010 Comdiv (F. Sadykov) - http://code.google.com/u/fagim.sadykov/
// Supported by Media Technology LTD 
//  
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//  
//      http://www.apache.org/licenses/LICENSE-2.0
//  
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// 
// MODIFICATIONS HAVE BEEN MADE TO THIS FILE
using System.IO;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using MvcContrib.Comdiv.Layers;
using MvcContrib.Comdiv.ViewEngines.Brail;
using MvcContrib.ViewFactories;
using NUnit.Framework;
using Rhino.Mocks;

namespace Comdiv.Brail.Tests{
    [TestFixture]
    [Category("BrailViewEngine")]
    public class BooViewEngineTester{
        #region Setup/Teardown

        [SetUp]
        public void SetUp(){
            _output = new StringWriter();
            _mocks = new MockRepository();
            _httpContext = _mocks.DynamicMock<HttpContextBase>(); //new TestHttpContext();
            var response = _mocks.DynamicMock<HttpResponseBase>();
            SetupResult.For(response.Output).Return(_output);
            SetupResult.For(_httpContext.Request).Return(_mocks.DynamicMock<HttpRequestBase>());
            SetupResult.For(_httpContext.Response).Return(response);
//			SetupResult.For(_httpContext.Session).Return(_mocks.DynamicMock<HttpSessionStateBase>());
            var requestContext = new RequestContext(_httpContext, new RouteData());
            _controller = _mocks.StrictMock<Controller>();
            _mocks.Replay(_controller);

            controllerContext = new ControllerContext(requestContext, _controller);
//			_viewContext = new ViewContext(controllerContext, null, new ViewDataDictionary(), null);

            _viewEngine = new BooViewEngine{
                                               //ViewSourceLoader = new FileSystemViewSourceLoader(VIEW_ROOT_DIRECTORY),
                                                Factory = new BrailViewFactory().configureLayers("brail", true, "MvcContrib_Existed_Tests"),
                                               Options = new BooViewEngineOptions(),
                                               SelfResolveRoot = "~/MvcContrib_Existed_Tests/Views"
                                           };
            _viewEngine.Initialize();
            _mocks.Replay(_httpContext);
        }

        #endregion

        private BooViewEngine _viewEngine;
        private ViewContext _viewContext;
        private HttpContextBase _httpContext;
        private MockRepository _mocks;
        private TextWriter _output;
        private Controller _controller;

        private static readonly string VIEW_ROOT_DIRECTORY = @"MvcContrib_Existed_Tests\Views";
        private ControllerContext controllerContext;

        private string GetViewOutput(string viewName){
            return GetViewOutput(viewName, null);
        }

        private string GetViewOutput(string viewName, string masterName){
            BrailBase view = _viewEngine.Process(viewName, masterName);
            _viewContext = new ViewContext(controllerContext, view, new ViewDataDictionary(), new TempDataDictionary());
            view.Render(_viewContext, _httpContext.Response.Output);
            return _httpContext.Response.Output.ToString();
        }

        [Test]
        public void Can_Render_SubView_with_custom_ViewData(){
            _mocks.ReplayAll();
            string expected = "View Test";
            string actual = GetViewOutput("view_CustomViewData");

            Assert.AreEqual(expected, actual);
        }

        [Test]
        public void Can_Render_View_With_Master_And_SubView(){
            _mocks.ReplayAll();

            string expected = "Master View SubView";
            string actual = GetViewOutput("view", "Master");

            Assert.AreEqual(expected, actual);
        }

      
        [Test]
        public void Layout_And_View_Should_Have_ViewContext(){
            _mocks.ReplayAll();
            //NOTE: path to master MUST be relative, no /
            BrailBase view = _viewEngine.Process("view", "Master");
            _viewContext = new ViewContext(controllerContext, view, new ViewDataDictionary(), new TempDataDictionary());
            view.Render(_viewContext, _httpContext.Response.Output);
            Assert.IsNotNull(view.ViewContext);
            Assert.AreEqual(view.ViewContext, view.Layout.ViewContext);
        }

        [Test]
        public void Request_ApplicationPath_Is_Placed_In_ViewData_With_SiteRoot_Key(){
            SetupResult.For(_httpContext.Request.ApplicationPath).Return("/ApplicationPath");
            _mocks.ReplayAll();

            string expected = "Current apppath is /ApplicationPath/";
            string actual = GetViewOutput("apppath");

            Assert.AreEqual(expected, actual);
        }

        [Test]
        public void Should_Use_Custom_Base_Class(){
            _mocks.ReplayAll();
            _viewEngine.Options.AssembliesToReference.Add(this.GetType().Assembly);
            _viewEngine.Options.BaseType =  "Comdiv.Brail.Tests.TestBrailBase";
            BrailBase view = _viewEngine.Process("view", null);
            Assert.IsInstanceOf<TestBrailBase>(view);
        }
    }

    public abstract class TestBrailBase : BrailBase{
        protected TestBrailBase(BooViewEngine viewEngine) : base(viewEngine) {}
    }
}